<template>
<div class="media-wrapper">
    <div
     v-if="globalStore.media_btn"
     class="upload-media-btn"
     @mouseenter="handleEnter"
     @mouseleave="handleLeave">
        <ul class="menu-upload">
            <li>
                <a-upload
                    name="common"
                    :showUploadList="false"
                    :multiple="true"
                    :headers="headers"
                    :customRequest="uploadMediaFile"
                    @click="is_clickUplad = true"
                    class="upload-select"
                >
                    <p>上传文件</p>
                </a-upload>
            </li>
            <li>
                <a-upload
                    name="directory"
                    :directory="true"
                    :showUploadList="false"
                    :multiple="true"
                    :headers="headers"
                    :customRequest="uploadMediaFile"
                    @click="is_clickUplad = true"
                    class="upload-select"
                >
                    <a-button>上传文件夹</a-button>
                </a-upload>
            </li>
        </ul>
    </div>
    <div v-if="globalStore.upload_model" class="media-uplad-page">
        <div class="media-upload-menu">
            <div class="media-upload-title">传输列表</div>
            <div class="media-upload-menu-content">
                <div class="media-upload-label">文件上传（{{ fileList && fileList.length }}）</div>
            </div>
        </div>
        <div class="media-upload-content">
            <div class="media-upload-header">
                <div class="media-upload-label">正在上传（<span>{{ uploadingLen }}/{{ fileList && fileList.length }}</span>）</div>
                <div class="media-upload-delete-all" @click="handleDeleteAll">
                    <i></i>
                    <span>全部清空</span>
                </div>
            </div>
            <div class="media-upload-body">
                <ul v-if="fileList && fileList.length > 0">
                    <li
                     v-for="item in fileList" 
                     :key="item.id" 
                     :class="{active: item.percent < 1 && item.percent > 0}"
                     class="media-upload-item">
                        <a href="javascript:;">
                            <div class="media-upload-item-img"><img :src="item.url"></div>
                            <div 
                            :class="{transform: item.state == 1}"
                            class="media-upload-item-info">
                                <p>{{ item.name }}</p>
                                <div class="media-progress" :style="{visibility: item.status == 2 ? 'hidden' : 'visible'}">
                                    <div class="media-progress-bar" :style="{ width: (item.percent * 100).toFixed(2) + '%' }"></div>
                                </div>
                                <div v-if="item.state == 1" class="media-speed-wrapper"><i></i>正在处理中...</div>
                                <div v-else class="media-speed-wrapper">
                                    <div class="media-size">
                                        <span v-if="item.state == 0">{{ formatSize(item.size * item.percent) }}/</span>
                                        <span>{{ formatSize(item.size) }}</span>
                                    </div>
                                    <div v-if="item.state == 0" class="media-speed">{{ (item.percent * 100).toFixed(2) }}%</div>
                                </div>
                            </div>
                            <div class="media-upload-item-option">
                                <span v-if="item.status == 1 && !item.pause" class="media-pause" @click="cancleUpload(item.id)"></span>
                                <span v-if="item.status == 1 && item.pause && !item.is_pause" class="media-resume" @click="resume(item.id)"></span>
                                <a-upload
                                    v-if="item.status == 1 && item.pause && item.is_pause"
                                    :name="item.id"
                                    :showUploadList="false"
                                    :multiple="true"
                                    :headers="headers"
                                    :customRequest="uploadMediaFile"
                                    @click="is_clickUplad = true"
                                    class="media-resume"
                                >
                                </a-upload>
                                <span v-if="item.state == 0" class="media-delete" @click="handleDelete(item.id)"></span>
                                <span v-if="item.status == 0 && item.percent == 0" class="media-wait"></span>
                                <span v-if="item.state == 2" class="media-folders" @click="navToDetail(item)"></span>
                                <span v-if="item.state == 1" class="media-folders transform" @click="navToNot"></span>
                            </div>
                        </a>
                    </li>
                </ul>
                <Emptys v-else />
            </div>
            <div v-if="fileList && fileList.length > 0" class="media-upload-switch">仅展示本日上传任务</div>
        </div>
    </div>
</div>
</template>
<script lang="ts" setup>
import { ref, onMounted } from 'vue';
import request from '@/service/axios';
import { Modal, message } from 'ant-design-vue';
import customSliceFileUploadMedia from "@/utils/customSliceFileUploadMedia";
import { formatSize } from "@/utils";
import Emptys from '@/views/videoLib/Emptys.vue'
import { useGlobalStore } from '@/store/global';
import { useFileInfoStore, FileItem } from '@/store/fileInfo';
import { useRouter, useRoute } from "vue-router";

type FileInfoHash = string;
type ElectronFile = File & { path: string };

const globalStore = useGlobalStore();
const useFileInfo = useFileInfoStore();
const router = useRouter();
const route = useRoute();

interface FileInfo {
    name:string;
    size: number;
    type: string;
    file: any;
}

const is_clickUplad = ref(false);
const isChangeDate = ref(false);
const uploadingLen = ref(0);
const fileList = ref<FileItem[]>([]);
const currentId = ref();
const headers = { authorization: "authorization-text" };
const userInfo = localStorage.getItem('userInfo') ? JSON.parse(localStorage.getItem('userInfo') || '') : {};

const uploadMediaFile = async (data: {
    file: ElectronFile | FileInfoHash;
    filename: string;
}) => {
    is_clickUplad.value = false;
    isChangeDate.value = true;
    // 调用上传
    const mediaUp = new customSliceFileUploadMedia(data.file, {
        directory_id: useFileInfo.directory_id,
        upload_type: data.filename
    });
    await mediaUp.start({onProgress, onFileInfo});

    // 判断是否断点续传
    if (data.filename != 'directory' && data.filename != 'common') {
        currentId.value = data.filename;
    }
    // 找到本次上传文件
    const idx = fileList.value.findIndex((item: any) => {
        if (data.filename != 'directory' && data.filename != 'common') {
            item.pause = false;
            item.is_pause = false;
        }
        return item.id == currentId.value;
    });
    fileList.value[idx]['instance'] = mediaUp;
    
    // 选择按钮隐藏
    globalStore.setMediaBtn(false);
    globalStore.setUploadModel(true);
}

// 显示上传选择
const handleEnter = () => {
    globalStore.setMediaBtn(true);
}

// 影藏上传选择
const handleLeave = () => {
    if (is_clickUplad.value) return;
    globalStore.setMediaBtn(false);
}

// 文件上传进度更新
const onProgress = (data: any) => {
    uploadingLen.value = 0;
    fileList.value.forEach((item: any) => {
        if (item.status == 1) {
            uploadingLen.value ++;
        }

        if (item.id === data.id) {
            item.percent = data.progress >= item.percent ? data.progress : item.percent;
            item.status = 1;

            // 上传成功
            if (data.progress === 1) {
                item.is_uploaded = 1;
                item.state = 1;
                item.status = 2;
            }
        }
    });
    useFileInfo.setUploadFileList(fileList.value);
};

// 上传信息 新建文件上传信息
const onFileInfo = (data: any) => {
    fileList.value.unshift({
        type: data.file.type,
        name: data.file.name,
        url: data.imgUrl,
        size: data.file.size,
        percent: 0,
        pause: false,
        is_pause: false,
        time: Date.now(),
        is_uploaded: 0,
        id: data.id,
        state: 0,
        status: 0,
        directory_id: useFileInfo.directory_id,
        userId: userInfo && userInfo.userId ? userInfo.userId : '',
        // directory_current: data.filename == "directory" ? directoryInfo.data.result.data.id : ''
    });
    useFileInfo.setUploadFileList(fileList.value);
    currentId.value = data.id;
};

// 暂停 取消上传
const cancleUpload = (id: string) => {
    const idx = fileList.value.findIndex((item: any) => {
        return item.id === id;
    });
    fileList.value[idx].pause = true;
    fileList.value[idx]['instance'] && fileList.value[idx]['instance'].stop();
}

//  继续上传
const resume = (id: string) => {
    const idx = fileList.value.findIndex((item: any) => {
        return item.id === id;
    });
    fileList.value[idx].pause = false;
    fileList.value[idx]['instance'] && fileList.value[idx]['instance'].resume();
}

// 删除单挑上传数据
const handleDelete = (id: string) => {
    Modal.confirm({
        content: '确定删除?',
        okText: '确认',
        cancelText: '取消',
        onOk() {
            request({
                method: "post",
                url: "/mediaslib-service/resource/task",
                data: {
                    id: id,
                    operation_type: 1,
                    task_type: 1
                },
            }).then((res) => {
                let arr:any[] = [];
                for (let i in fileList.value) {
                    if (fileList.value[i].id == id) {
                        if(fileList.value[i].pause && !fileList.value[i].is_pause) {
                            fileList.value[i]['instance'] && fileList.value[i]['instance'].delFileInfo();
                            fileList.value[i]['instance'] && fileList.value[i]['instance'].stop();
                        }
                        continue;
                    }
                    arr.push(fileList.value[i]);
                }
                fileList.value = arr;
                useFileInfo.setUploadFileList(fileList.value);
                message.success('删除成功！');
            }).catch(err => {
                console.log(err);
                console.log(err.response);
            });
        }
    });
}

// 删除所有
const handleDeleteAll = () => {
    Modal.confirm({
        content: '确定清楚上传数据?',
        okText: '确认',
        cancelText: '取消',
        onOk() {
            request({
                method: "post",
                url: "/mediaslib-service/resource/task",
                data: {
                    operation_type: 2,
                    task_type: 1
                },
            }).then((res) => {
                let arr:any[] = [];
                for (let i in fileList.value) {
                    if (fileList.value[i].status == 0 || fileList.value[i].status == 1) {
                        if(fileList.value[i].pause && !fileList.value[i].is_pause) {
                            fileList.value[i]['instance'] && fileList.value[i]['instance'].delFileInfo();
                            fileList.value[i]['instance'] && fileList.value[i]['instance'].stop();
                        }
                        continue;
                    }
                    arr.push(fileList.value[i]);
                }
                fileList.value = arr;
                useFileInfo.setUploadFileList(fileList.value);
                message.success('删除成功！');
            }).catch(err => {
                console.log(err);
                console.log(err.response);
            });
        }
    });
}

// 初始化上传数据
const checkLocalList = () => {
    let nowStr = Date.now();
    let arr:any = [];
    let tempFileList = fileList.value;
    const localFileList = localStorage.getItem('localFileList') ? JSON.parse(localStorage.getItem('localFileList') || '') : [];
    fileList.value = localFileList.uploadFileList;
    
    for (let i in fileList.value) {
        let tempNow = fileList.value[i].time || 0;
        if (userInfo && fileList.value[i].userId != userInfo.userId) continue;
        if (nowStr - tempNow > 24 * 60 * 60 * 1000) continue;
        arr.push(fileList.value[i]);
    }
    // 降序
    arr.sort((a:any, b:any) => {
        if (a.time && b.time) return b.time - a.time;
    });
    
    request({
        method: "get",
        url: "/mediaslib-service/resource/task",
        params: {
            last_id: 0,
            first_id: 0,
            query_type: 1
        },
    }).then((res) => {
        let arrList = res.data.result.data || [];

        for (let i in arrList) {
            arrList[i]["url"] = arrList[i].thumbnail;
            arrList[i]["status"] = arrList[i].upload_status;
            arrList[i]["state"] = arrList[i].upload_state;
            arrList[i]["time"] = arrList[i].create_time;
            if (arrList[i].status == 2) arrList[i].percent = 1;
        }

        let mergeArr = arr.concat(arrList);
        for (let i = 0; i < mergeArr.length; i++) {
            for (let j = i + 1; j < mergeArr.length; j++) {
                if (mergeArr[i].id == mergeArr[j].id) {
                    if (mergeArr[i].status == 1) {
                        mergeArr[i].url = mergeArr[j].url;
                        mergeArr[i].state = mergeArr[j].state;
                        mergeArr[i].percent = mergeArr[i].percent || 0.1;
                        if (mergeArr[j].state == 2) mergeArr[i].status = 2;
                    }
                    mergeArr.splice(j, 1);
                    j--;
                }
            }
            mergeArr[i].userId = userInfo.userId;
        }

        // 取内存中的实例
        for (let i in mergeArr) {
            for (let j in tempFileList) {
                if (mergeArr[i].id == tempFileList[j].id && mergeArr[i].status == 1) {
                    mergeArr[i].instance = tempFileList[j].instance;
                }
            }
        }
        
        useFileInfo.setUploadFileList(mergeArr);
    });
};

const navToNot = () => {
    message.info('媒资文件正在处理中...');
}

// 跳转到详情页
const navToDetail = (data: any) => {
    router.push(`/admin/mediaDetails?id=${data.id}`);
}

// websocket
const token = localStorage.getItem('token');
const prefix = import.meta.env.VITE_APP_WS;
const wsUrl =
    prefix +
    "/mediaslib-messagecenter/ws?platform=web&access_token=" +
    token;
let closeTime = 0;
const webSocket = () => {
    if ("WebSocket" in window) {
        console.log("您的浏览器支持WebSocket");
        const ws = new WebSocket(wsUrl);

        ws.onopen = function (evt) {
            console.log("WebSocket open");
        };

        // 心跳
        let timmer = setInterval(() => {
            ws.send("ping");
        }, 1000 * 10);

        ws.onmessage = function (evt) {
            const data = JSON.parse(evt.data);
            console.log("message:" + JSON.stringify(data));
            // 媒资上传刷新
            if (data.result.data.type == 21) {
                useFileInfo.setProcessStatus({
                    refresh: data.result.data.body.isFresh,
                    refresh_type: data.result.data.body.status,
                    websocketInfo: data.result.data.body.websocketInfo
                });
            }
        };

        ws.onclose = function (evt) {
            console.log("WebSocket close");
            if (timmer) clearInterval(timmer);

            closeTime++;
            if (closeTime > 5) {
                setTimeout(() => {
                    webSocket();
                }, 1000 * 30);
            } else if (closeTime > 10) {
                setTimeout(() => {
                    webSocket();
                }, 1000 * 60 * 5);
            } else {
                webSocket();
            }
        };

        ws.onerror = function (evt) {
            console.log("WebSocket error");
        };
    } else {
        console.log("您的浏览器不支持WebSocket");
    }
};

onMounted(() => {
    checkLocalList();
    webSocket();

    window.addEventListener("beforeunload", (event) => {
        if (isChangeDate.value) {
            // 如果离开，更下下任务列表
            for (let i in fileList.value) {
                if (fileList.value[i].status == 1) {
                    fileList.value[i].pause = true;
                    fileList.value[i].is_pause = true;
                }
            }
            useFileInfo.setUploadFileList(fileList.value);
            let e = window.event || event;
            event.preventDefault();
            if (e) {
                e.returnValue = "确定离开吗？";
            }
            return "确定离开吗？";
        }
    });

    fileList.value.forEach((item) => {
        if (item.status == 1) {
            uploadingLen.value ++;
        }
    });
});

watch(
    () => globalStore.upload_model,
    (val) => {
        if (globalStore.upload_model) {
            checkLocalList();
        }
    },
    {
        immediate: true,
        deep: true
    }
);
</script>

<style lang="scss" src="./index.scss" scoped></style>